
package com.hlkj.pay.app.merchant.ext.impl.heepay.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSONObject;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.heepay.HeePayScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.heepay.constanct.HeePayConstant;
import com.hlkj.pay.app.merchant.ext.impl.heepay.constanct.HeePayExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.heepay.dto.HeePayConfig;
import com.hlkj.pay.app.merchant.ext.impl.heepay.handler.HeePayMerchantCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.heepay.util.HeePaySignUtil;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

/**
 * 条码支付，商户扫用户二维码收款
 * 
 * @author HlpayTeam
 * @date 2024/11/18 13:08
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = HeePayExtConstant.QUICK)
public class HeePayQuickPayOrderExtPt extends HeePaySceneCommonPayOrder implements HeePayScenePayOrderExtPt {

    @Value("${hlkj.domain}")
    private String domain;

    @Autowired
    private HeePayMerchantCommonParamsHandle heePayMerchantCommonParamsHandle;

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        // 配置转换
        CommonResult<HeePayConfig> commonResult = heePayMerchantCommonParamsHandle.heePayConfig(channelPayOrderContext.getProviderChannelConfigDO(),
                channelPayOrderContext.isTest());
        HeePayConfig heePayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        heePayMerchantCommonParamsHandle.heePayAppChannelParams(merchantAppChannelDO, heePayConfig);
        try {

            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", payOrderDO.getPayOrderNo());
            bizContent.put("out_trade_time", DateUtils.getDateString(DatePattern.NORM_DATETIME_PATTERN));
            bizContent.put("pay_amt", payOrderDO.getAmount());
            bizContent.put("time_expire", 29);
            bizContent.put("pay_type", "63");
            bizContent.put("notify_url", channelPayOrderContext.getNotifyUrl());
            bizContent.put("return_url", channelPayOrderContext.getRedirectUrl());

            JSONObject payerInfo = new JSONObject();
            PayOrderCommonParamReq.Extra extra = channelPayOrderContext.getExtra();
            if (StringUtils.hasText(extra.getUserId())) {
                payerInfo.put("merch_user_id", extra.getUserId());
            } else {
                if (payOrderDO.getMchOrderNo().length() > 30)
                    payerInfo.put("merch_user_id", payOrderDO.getMchOrderNo().substring(0,29));
                else
                    payerInfo.put("merch_user_id", payOrderDO.getMchOrderNo());
            }
            bizContent.put("payer_info", payerInfo);

            JSONObject goodsInfo = new JSONObject();
            goodsInfo.put("goods_name", payOrderDO.getSubject());
            bizContent.put("goods_info", goodsInfo);
            
            if (!PayOrderEnums.FUND_PROCESS_TYPE.NO.getCode().equals(payOrderDO.getFundProcessType())) {
                bizContent.put("is_profit_sharing", 1);
            }

            JSONObject params = new JSONObject();
            params.put("biz_content", JsonUtils.toJsonString(bizContent));
            params.put("merch_id", heePayConfig.getAgentId());
            params.put("method", "heepay.bank.apply.page.pay");
            params.put("sign_type", "RSA1");
            params.put("timestamp", DateUtils.getDateString(DatePattern.NORM_DATETIME_PATTERN));
            params.put("version", "1.0");

            log.info("汇付宝 快捷支付 请求参数:{}", JsonUtils.toJsonString(params));
            CommonResult<String> resultResult = heePayMerchantCommonParamsHandle.heePayOrderRequest(HeePayConstant.PAY_ORDER_CASHIER, heePayConfig, params);
            log.info("汇付宝 快捷支付 返回参数:{}", resultResult.getData());
            if (!resultResult.isSuccess()) {
                channelPayOrderContext.setRemark("汇付宝快捷支付请求失败,失败信息:" + resultResult.getMsg());
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            String response = resultResult.getData();
            JSONObject heePayOrderSubmitRes = JSONObject.parseObject(response);

            if ("10000".equals(heePayOrderSubmitRes.getString("code"))) {
                String rspContent = HeePaySignUtil.decrypt(heePayOrderSubmitRes.getString("data"), heePayConfig.getPrivateKey());
                JSONObject bizObj = JSONObject.parseObject(rspContent);
                channelPayOrderContext.setPayDataType("url");
                channelPayOrderContext.setPayInfo(bizObj.getString("redirect_uri"));
            }
            else {
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                String errorMsg = heePayOrderSubmitRes.getString("msg") + heePayOrderSubmitRes.getString("sub_msg");
                if (StringUtils.hasText(errorMsg)) {
                    channelPayOrderContext.setRemark(errorMsg);
                }
                else {
                    channelPayOrderContext.setRemark("汇付宝提交快捷支付返回错误信息为空,错误码为:" + heePayOrderSubmitRes.getString("code"));
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("汇付宝提交快捷支付请求失败 message:{}", e.getMessage(), e);
            channelPayOrderContext.setRemark("汇付宝提交快捷支付请求失败,失败信息:" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonCloseChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelClosePayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonQueryRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }
}
